<?php

// 应用公共文件

use think\facade\Env;
use app\common\exception\BaseException;
use DfaFilter\SensitiveHelper;

function render_array_success($data = [], $msg = 'success'): array
{
    return render_array(config('status.success'), $msg, $data);
}

function render_array_error($msg = 'error', $data = []): array
{
    return render_array(config('status.error'), $msg, $data);
}

function render_array($code, $msg, $data): array
{
    return compact('code', 'msg', 'data');
}

// 重写trim方法 (解决int类型过滤后后变为string类型)
function my_trim($str)
{
    return is_string($str) ? trim($str) : $str;
}

// 重写htmlspecialchars方法 (解决int类型过滤后后变为string类型)
function my_htmlspecialchars($string)
{
    return is_string($string) ? htmlspecialchars($string, ENT_COMPAT) : $string;
}

// 敏感字过滤
function filter_word($content)
{
    if ($content) {
        $sensitive_word_file =  public_path(). 'static\text\sensitive_word.txt';
        $handle = SensitiveHelper::init()->setTreeByFile($sensitive_word_file);
        $content = $handle->replace($content, '*', true);
    }
    return $content;
}

// 输出错误信息
function throwError(string $message, ?int $status = null, array $data = [])
{
    is_null($status) && $status = config('status.error');
    throw new BaseException($message, $status, $data);
}

// 下划线转驼峰
function camelize(string $uncamelized_words, string $separator = '_'): string
{
    $uncamelized_words = $separator . str_replace($separator, " ", strtolower($uncamelized_words));
    return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator);
}

// 驼峰转下划线
function uncamelize(string $camelCaps, string $separator = '_'): string
{
    return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}

// 获取全局唯一标识符
function get_guid_v4(bool $trim = true): string
{
    // Windows
    if (function_exists('com_create_guid') === true) {
        $charid = com_create_guid();
        return $trim ? trim($charid, '{}') : $charid;
    }
    // OSX/Linux
    if (function_exists('openssl_random_pseudo_bytes') === true) {
        $data = openssl_random_pseudo_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);    // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);    // set bits 6-7 to 10
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
    // Fallback (PHP 4.2+)
    mt_srand(intval((double)microtime() * 10000));
    $charid = strtolower(md5(uniqid((string)rand(), true)));
    $hyphen = chr(45);                  // "-"
    $lbrace = $trim ? "" : chr(123);    // "{"
    $rbrace = $trim ? "" : chr(125);    // "}"
    return $lbrace .
        substr($charid, 0, 8) . $hyphen .
        substr($charid, 8, 4) . $hyphen .
        substr($charid, 12, 4) . $hyphen .
        substr($charid, 16, 4) . $hyphen .
        substr($charid, 20, 12) .
        $rbrace;
}

// 当前是否为调试模式
function is_debug(): bool
{
    return (bool)Env::instance()->get('APP_DEBUG');
}

// BK 转 UTF-8
function gbkToUtf8($value)
{
    if (is_array($value)) {
        foreach ($value as $key => $val) {
            $value[$key] = is_array($val) ? gbkToUtf8($value[$key]) : iconv("GBK", "UTF-8", $val);
        }
    } else {
        $value = iconv("GBK", "UTF-8", $value);
    }
    return $value;
}

// UTF-8 转 GBK
function utf8ToGbk($value)
{
    if (is_array($value)) {
        foreach ($value as $key => $val) {
            $value[$key] = is_array($val) ? utf8ToGbk($value[$key]) : iconv("UTF-8", "GBK", $val);
        }
    } else {
        $value = iconv("UTF-8", "GBK", $value);
    }
    return $value;
}

// 多维数组合并
function array_merge_multiple($array1, $array2): array
{
    $merge = $array1 + $array2;
    $data = [];
    foreach ($merge as $key => $val) {
        if (
            isset($array1[$key])
            && is_array($array1[$key])
            && isset($array2[$key])
            && is_array($array2[$key])
        ) {
            $data[$key] = is_assoc($array1[$key]) ? array_merge_multiple($array1[$key], $array2[$key]) : $array2[$key];
        } else {
            $data[$key] = $array2[$key] ?? $array1[$key];
        }
    }
    return $data;
}

/**
 * 生成随机字符串
 * @param int $length 生成长度
 * @param int $type 生成类型：0-小写字母+数字，1-小写字母，2-大写字母，3-数字，4-小写+大写字母，5-小写+大写+数字
 * @return string
 */
function generate_rand_str($length = 8, $type = 0) : string
{
    $a = 'abcdefghijklmnopqrstuvwxyz';
    $A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $n = '0123456789';

    switch ($type) {
        case 1: $chars = $a; break;
        case 2: $chars = $A; break;
        case 3: $chars = $n; break;
        case 4: $chars = $a.$A; break;
        case 5: $chars = $a.$A.$n; break;
        default: $chars = $a.$n;
    }

    $str = '';
    for ($i = 0; $i < $length; $i++) {
        $str .= $chars[ mt_rand(0, strlen($chars) - 1) ];
    }
    return $str;
}

if (!function_exists('matchLatLng')) {
    function matchLatLng($latlng) {
        $match = "/^\d{1,3}\.\d{1,30}$/";
        return preg_match($match, $latlng) ? $latlng : 0;
    }
}

/**
 * 计算距离
 */
if (!function_exists('getDistanceBuilder')) {
    function getDistanceBuilder($lat, $lng) {
        return "ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((". matchLatLng($lat) . " * PI() / 180 - latitude * PI() / 180) / 2), 2) + COS(". matchLatLng($lat). " * PI() / 180) * COS(latitude * PI() / 180) * POW(SIN((". matchLatLng($lng). " * PI() / 180 - longitude * PI() / 180) / 2), 2))) * 1000) AS distance";
    }
}

/**
 * 后端防抖
 */
if (!function_exists('repeat_filter')) {
    function repeat_filter($key = null, $expire = 5)
    {
        if (!$key) {
            $url = request()->baseUrl();
            $ip = request()->ip();

            $key = md5($url . ':' . $ip);
        }

        $hasRedis = config('redis');
        if ($hasRedis) {
            $redis = (new \addons\shopro\library\Redis())->getRedis();
            if ($redis->exists($key)) {
                throw new \addons\shopro\exception\Exception('请不要重复提交');
            }
            $redis->setex($key, $expire, time());     // 缓存 五秒
        } else {
            if (cache('?' . $key)) {
                throw new \addons\shopro\exception\Exception('请不要重复提交');
            }
            cache($key, time(), $expire);
        }
    }
}
